package com.linrung.gdsfrz;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.fusesource.hawtbuf.ByteArrayInputStream;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import cn.hutool.core.io.FileUtil;
import cn.hutool.json.JSONUtil;

import com.linrung.core.model.ResultData;
import com.linrung.core.utils.AppContextUtils;
import com.linrung.core.utils.SpringPropertyUtils;
import com.linrung.core.utils.StringTools;

/**
 * 请求接口工具类
 *
 * @author wurenlong
 */
public class RequestApiUtils {

    private static Logger logger = Logger.getLogger(RequestApiUtils.class);

    /**
     * API网关类型：统一认证平台
     */
    public final static String API_TYPE_TYPT="GDS_TYPT_";

    /**
     * API网关类型：公文交换
     */
    public final static String API_TYPE_DOC_EXCHANGE="GDS_DOC_EXCHANGE_";

    /**
     * API网关类型：电子印章
     */
    public final static String API_TYPE_E_SEAL="GDS_ESEAL_";

    private static final String CACHE_CONTROL = "no-cache";

    public static final String HEADER_CONTENT_TYPE_EMPTY = "null";


    private static String API_FILE_UPLOAD = "/ebus/odexchange/cgi-bin/media/upload3";
    private static String API_FILE_DOWNLOAD = "/ebus/odexchange/cgi-bin/media/get3";
    public static String API_PULL_DOC="/ebus/sgbackend/api/r/bc/odexchangesys/PullDoc";
    private static String API_SHORT_DOC = "/ebus/sgbackend/api/r/bc/odexchangesys/SendShortDoc";


    public static String DOC_RETRACT_QUEUE_NAME = "retract.gdsdoc.queue";
    public static String DOC_SEND_QUEUE_NAME = "send.gdsdoc.queue";

    public static String MSG_KEY_RECEIVER_ORG_IDS = "receivOrgIds";
    public static String MSG_KEY_RECEIVER_DEPARTMENT_ID = "receiverDepartmentId";
    public static String MSG_KEY_RECEIVER_DEPARTMENT_NAME = "receiverDepartmentName";
    public static String MSG_KEY_SENDER_DEPARTMENT_ID = "senderDepartmentId";
    public static String MSG_KEY_SELF_SYS_MASTER_SLAVE_ORG_ID = "selfSysMasterSlaveOrgId";
    public static String MSG_KEY_SELF_SYS_RECEIVE_ORG_REGION_CODE = "selfSysReceiveOrgRegionCode";
    public static String MSG_KEY_DOC_ID = "id";
    public static String MSG_KEY_SELF_SYS_ORG_ID = "selfSysOrgId";
    public static String MSG_KEY_SEGMENT_ID = "segmentId";

    public static String MSG_KEY_ISSUDE_ARC_ID = "arcId";
    public static String MSG_KEY_ISSUDE_RECEIVE_ID = "receiveId";

    public static String MSG_KEY_JMS_TYPE = "jmsType";
    public static String JMS_TYPE_SEND_DOC = "sendDoc";
    public static String JMS_TYPE_RECEIVE_DOC = "receiveDoc";


    public static String SEGMENT_TYPE_OFC = "OFC";
    public static String SEGMENT_TYPE_RET = "RET";

    /**
     * 下载文件
     * @param apiUrl 请求地址
     * @param params 请求参数
     * @param apiType 请求类型
     * @param headerMap 请求header
     * @param realPath 存储文件绝对路径
     * @param pathPrefix 存储文件的文件夹(追加在realPath后面)
     * @param httpMethod
     * @return
     * @throws Exception
     */
    public static ResultData<Object> downloadFile(String apiUrl, Map<String, Object> params, String apiType,
                                                  Map<String, String> headerMap, String realPath, String pathPrefix, HttpMethod httpMethod) throws Exception {
        ResultData<Object> rd = ResultData.FAILURE();
        if(HttpMethod.GET == httpMethod) {
            rd = downloadFileByGet(apiUrl, params, apiType, headerMap, realPath, pathPrefix);
        } else {
        }
        return rd;
    }

    /**
     * post 请求
     * @param apiUrl API地址
     * @param params 请求参数
     * @param apiType API类型
     * @return
     * @throws Exception
     */
    public static JSONObject post(String apiUrl, Map<String, Object> params, String apiType) throws Exception {
        return commonPost(apiUrl, params, apiType);
    }

    /**
     * post 请求
     * @param apiUrl API地址
     * @param params 请求参数
     * @param apiType API类型
     * @param headerMap 请求头部
     * @return
     * @throws Exception
     */
    public static JSONObject post(String apiUrl, Map<String, Object> params, String apiType, Map<String, String> headerMap) throws Exception {
        return commonPost(apiUrl, params, apiType, headerMap);
    }

    /**
     * get 请求
     * @param apiUrl API地址
     * @param params 请求参数
     * @param apiType API类型
     * @return
     * @throws Exception
     */
    public static JSONObject get(String apiUrl, Map<String, Object> params, String apiType) throws Exception {
        return commonGet(apiUrl, params, apiType);
    }

    /**
     * get 请求
     * @param apiUrl API地址
     * @param params 请求参数
     * @param apiType API类型
     * @param headerMap 请求头部
     * @return
     * @throws Exception
     */
    public static JSONObject get(String apiUrl, Map<String, Object> params, String apiType, Map<String, String> headerMap) throws Exception {
        return commonGet(apiUrl, params, apiType, headerMap);
    }

    public static JSONObject postForDocExchange(String apiUrl, Map<String, Object> params) throws Exception {
        return commonPost(apiUrl, params, API_TYPE_DOC_EXCHANGE);
    }

    public static JSONObject getForDocExchange(String apiUrl, Map<String, Object> params) throws Exception {
        return commonGet(apiUrl, params, API_TYPE_DOC_EXCHANGE);
    }

    public static JSONObject postShortDocExchange(String segmentId, String type, long time, String opinion, String senderOrgId, String senderOrgName, String receiveOrgId, String receiveOrgName, Map<String, Object> extAttrs) {
        List<Map<String, Object>> attrs = new ArrayList<>();

        if(extAttrs != null) {
            Set<String> keys = extAttrs.keySet();
            for(String key : keys) {
                Object val = extAttrs.get(key);

                Map<String, Object> attr = new HashMap<String, Object>();
                attr.put("key", key);
                attr.put("value", val);
                attrs.add(attr);
            }
        }

        Map<String, Object> extAttr = new HashMap<String, Object>();
        extAttr.put("attrs", attrs);

        if(time==0) {
            time = System.currentTimeMillis();
        }

        time = time / 1000;

        Map<String, Object> segment = new HashMap<>();
        segment.put("segment_id", segmentId);
        segment.put("type", type);
        segment.put("time", time);
        segment.put("opinion", opinion);

        Map<String, Object> params = new HashMap<>();
        params.put("segment_type", "RET");
        params.put("segment", segment);

        Map<String, Object> sendOrgMap = new HashMap<String, Object>();
        sendOrgMap.put("department_id",senderOrgId);
        sendOrgMap.put("department_name", senderOrgName);
        sendOrgMap.put("department_desc", "");
        params.put("sender_department", sendOrgMap);

        List<Map<String, Object>> receiveOrgList = new ArrayList<>();
        Map<String, Object> receiveOrgMap = new HashMap<String, Object>();
        receiveOrgMap.put("department_id", receiveOrgId);
        receiveOrgMap.put("department_name", receiveOrgName);
        receiveOrgMap.put("department_desc", "");
        receiveOrgList.add(receiveOrgMap);
        params.put("receiver_department", receiveOrgList);

        params.put("ext", extAttr);
        logger.info(String.format("发送短报文参数：%s", JSONUtil.toJsonStr(params)));
        try {
            JSONObject jsonObject = RequestApiUtils.postForDocExchange(API_SHORT_DOC, params);
            return jsonObject;
        } catch (Exception e) {
            logger.error("发送短报文异常：", e);
            JSONObject jsonObject = new JSONObject();
            jsonObject.put(ERROR_CODE, 500);
            jsonObject.put(ERROR_MSG, e.getMessage());
            return jsonObject;
        }
    }

    /**
     * post 上传文件
     * @param file 上传文件
     * @param fileParamsName 上传文件参数名，默认 file
     * @param fileName 上传文件名称
     * @param apiUrl apiURL
     * @param apiType api类型
     * @param extParams 扩展参数，追加在链接后面
     * @param headerMap 请求头参数
     * @return JSONObject
     * @throws Exception
     */
    public static JSONObject postUpload(File file, String fileParamsName, String fileName, String apiUrl, String apiType, Map<String, String> extParams, Map<String, String> headerMap) throws Exception {
        String paasId = getPaasId(apiType);
        String paasToken = getPaasToken(apiType);
        String serverUrl = getServerUrl(apiType);
        if(StringTools.isBlank(paasId) || StringTools.isBlank(paasToken) || StringTools.isBlank(serverUrl)) {
            throw new NullPointerException("获取基础配置失败：paasId、paasToken、serverUrl。");
        }
        String requestURL = serverUrl.concat(apiUrl);
        Signature sign = new Signature(paasId, paasToken);
        RestTemplate restTemplate = AppContextUtils.getBean(RestTemplate.class);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        headers.setCacheControl(CACHE_CONTROL);
        headers.add("x-tif-paasid", sign.getPaasId());
        headers.add("x-tif-timestamp", sign.getTimestamp());
        headers.add("x-tif-signature", sign.getSignature());
        headers.add("x-tif-nonce", sign.getNonce());
        headers.add(HttpHeaders.CONTENT_LENGTH, String.valueOf(file.length()));

        boolean heanderIsNull = null == headerMap || headerMap.isEmpty() || headerMap.size() == 0;
        if(!heanderIsNull) {
            headerMap.remove(HttpHeaders.CACHE_CONTROL);
            headerMap.remove(HttpHeaders.CONTENT_TYPE);
            headerMap.remove("x-tif-paasid");
            headerMap.remove("x-tif-timestamp");
            headerMap.remove("x-tif-signature");
            headerMap.remove("x-tif-nonce");
            if(headerMap.size() > 0) {
                for(Map.Entry<String, String> kentry : headerMap.entrySet()) {
                    if(StringTools.isNotBlank(kentry.getValue())) {
                        headers.add(kentry.getKey(), kentry.getValue());
                    }
                }
            }
        }

        if(extParams != null && extParams.size() > 0) {
            String paramsstring = "?time=" + System.nanoTime();
            Set<String> keySet = extParams.keySet();
            for (String key : keySet) {
                paramsstring = paramsstring.concat("&").concat(key).concat("=").concat(extParams.get(key));
            }
            requestURL = requestURL.concat(paramsstring);
        }

        CustomerFileSystemResource fileSystemResource = new CustomerFileSystemResource(file, fileName);
        MultiValueMap<String, Object> form = new LinkedMultiValueMap<>();
        form.add(StringTools.defaultIfBlank(fileParamsName, "file"), fileSystemResource);
        //用HttpEntity封装整个请求报文
        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<MultiValueMap<String, Object>>(form, headers);
        JSONObject respJson = restTemplate.postForObject(requestURL, requestEntity, JSONObject.class);
        return respJson;
    }


    /**
     *
     * @param serverUrl 服务地址
     * @param apiCode
     * @param params
     * @param sign
     * @return
     * @throws Exception
     */
    public static JSONObject commonPost(String apiUrl, Map<String, Object> params, String apiType) throws Exception {
        return commonPost(apiUrl, params, apiType, null);

    }

    /**
     * 提交请求
     * @param apiUrl
     * @param params
     * @param apiType
     * @param headerMap
     * @return
     * @throws Exception
     */
    public static JSONObject commonPost(String apiUrl, Map<String, Object> params, String apiType, Map<String, String> headerMap) throws Exception {
//		if (!API_MAP.containsKey(apiCode)) {
//			throw new Exception("无效ApiCode，无法找到对应的调用信息，apiCode=" + apiCode);
//		}
        String paasId = getPaasId(apiType);
        String paasToken = getPaasToken(apiType);
        String serverUrl = getServerUrl(apiType);
        if(StringTools.isBlank(paasId) || StringTools.isBlank(paasToken) || StringTools.isBlank(serverUrl)) {
            throw new NullPointerException("获取基础配置失败：paasId、paasToken、serverUrl。");
        }
        Signature sign = new Signature(paasId, paasToken);

        RestTemplate restTemplate = AppContextUtils.getBean(RestTemplate.class);
        //当没有请求头信息时
//		MultiValueMap<String, Object> postParameters = new LinkedMultiValueMap<>();
//		if(params != null) {
//			Set<String> keySet = params.keySet();
//			for (String key : keySet) {
//				postParameters.add(key, params.get(key));
//			}
//		}

        boolean heanderIsNull = null == headerMap || headerMap.isEmpty() || headerMap.size() == 0;
        HttpHeaders headers = new HttpHeaders();
        if(!heanderIsNull && headerMap.containsKey(HttpHeaders.CONTENT_TYPE)) {
            headers.setContentType(MediaType.valueOf(headerMap.get(HttpHeaders.CONTENT_TYPE)));
            headers.remove(HttpHeaders.CONTENT_TYPE);
        } else {
            headers.setContentType(MediaType.APPLICATION_JSON);
        }
        if(!heanderIsNull && headerMap.containsKey(HttpHeaders.CACHE_CONTROL)) {
            headers.setCacheControl(headerMap.get(HttpHeaders.CACHE_CONTROL));
            headers.remove(HttpHeaders.CACHE_CONTROL);
        } else {
            headers.setCacheControl(CACHE_CONTROL);
        }
        if(!heanderIsNull) {
            headerMap.remove("x-tif-paasid");
            headerMap.remove("x-tif-timestamp");
            headerMap.remove("x-tif-signature");
            headerMap.remove("x-tif-nonce");
        }
        headers.add("x-tif-paasid", sign.getPaasId());
        headers.add("x-tif-timestamp", sign.getTimestamp());
        headers.add("x-tif-signature", sign.getSignature());
        headers.add("x-tif-nonce", sign.getNonce());
        if(!heanderIsNull && headerMap.size() > 0) {
            for(Map.Entry<String, String> kentry : headerMap.entrySet()) {
                if(StringTools.isNotBlank(kentry.getValue())) {
                    headers.add(kentry.getKey(), kentry.getValue());
                }
            }
        }

//		HttpEntity<MultiValueMap<String, Object>> request = new HttpEntity<MultiValueMap<String, Object>>(
//				postParameters, headers);
        HttpEntity<Map<String, Object>> request = new HttpEntity<>(params, headers);
//		logger.info(String.format("REST POST请求：%s", apiUrl));
        JSONObject result = restTemplate.postForObject(serverUrl + apiUrl, request, JSONObject.class);
        return result;
    }

    public static JSONObject commonGet(String apiUrl, Map<String, Object> params,  String apiType) throws Exception {
        return  commonGet(apiUrl, params, apiType, null);
    }

    /**
     * Get 请求
     * @param apiUrl 请求地址
     * @param params 请求参数
     * @param apiType 请求类型
     * @param headerMap 请求header
     * @return
     * @throws Exception
     */
    public static JSONObject commonGet(String apiUrl, Map<String, Object> params,  String apiType, Map<String, String> headerMap) throws Exception {
        ResponseEntity<JSONObject> responseResult = commonGet(apiUrl, params, apiType, headerMap, JSONObject.class);
        return  responseResult.getBody();
    }

    /**
     * Get 请求方式下载文件
     * @param apiUrl 请求地址
     * @param params 请求参数
     * @param apiType 请求类型
     * @param headerMap 请求header
     * @param realPath 存储文件绝对路径
     * @param pathPrefix 存储文件的文件夹(追加在realPath后面)
     * @return
     * @throws Exception
     */
    public static ResultData<Object> downloadFileByGet(String apiUrl, Map<String, Object> params, String apiType,
                                                       Map<String, String> headerMap, String realPath, String pathPrefix) throws Exception {
        ResponseEntity<byte[]> responseResult = commonGet(apiUrl, params, apiType, headerMap, byte[].class);
        HttpHeaders responseHeaders = responseResult.getHeaders();
        List<String> contentDispositionList = responseHeaders.get("Content-Disposition");
        String fileName = "";
        if(contentDispositionList != null) {
            for(String contentDisposition : contentDispositionList) {
                if(StringUtils.containsIgnoreCase(contentDisposition, "filename")) {
                    fileName = contentDisposition.split("=")[1];
                    if(StringUtils.isNotBlank(fileName) && fileName.endsWith("\"")) {
                        fileName = fileName.substring(0, fileName.length() -1);
                    }
                }
            }
        }
        String extensionFileName = StringUtils.defaultIfBlank(FilenameUtils.getExtension(fileName), "");
        String localFileName = StringTools.generateUUID() + "." + extensionFileName;
        HttpStatus httpStatus = responseResult.getStatusCode();
        int status = httpStatus.value();
        if(status != 200) {
            throw new RuntimeException(String.format("下载附件出错，url=%s, httpStatus=%d", apiUrl, status));
        }
        ResultData<Object> rd = ResultData.FAILURE();
        byte[] rpsByte = responseResult.getBody();
        if(responseHeaders.getContentType().includes(MediaType.APPLICATION_OCTET_STREAM)) {
            String path = null;
            if(rpsByte != null) {
                InputStream is = new ByteArrayInputStream(rpsByte);
                path = saveFile(is, realPath, pathPrefix, localFileName);
                Map<String, Object> rspData = new HashMap<String, Object>();
                rspData.put("filePath", path);
                rspData.put("fileName", localFileName);
                rspData.put("fileLength", is.available());
                rd = ResultData.SUCCESS();
                rd.setData(rspData);
            } else {
                logger.error(String.format("没有文件，忽略，url=%s, httpStatus=%d， fileName=%s", apiUrl, status, fileName));
                rd.setDesc("空文件");
            }
        } else {
            StringBuffer resultsb = new StringBuffer();
            @SuppressWarnings("resource")
            BufferedReader br = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(rpsByte)));
            String line = null;
            while ((line = br.readLine()) != null) {
                resultsb.append(line);
            }
            rd.setData(resultsb.toString());
        }
        return rd;
    }

    /**
     * Get 请求
     * @param apiUrl 请求地址
     * @param params 请求参数
     * @param apiType 请求类型
     * @param headerMap 请求header
     * @param classes 返回类
     * @return
     * @throws Exception
     */
    public static <T>ResponseEntity<T> commonGet(String apiUrl, Map<String, Object> params, String apiType, Map<String, String> headerMap, Class<T> classes) throws Exception {
        String paasId = getPaasId(apiType);
        String paasToken = getPaasToken(apiType);
        String serverUrl = getServerUrl(apiType);
        if(StringTools.isBlank(paasId) || StringTools.isBlank(paasToken) || StringTools.isBlank(serverUrl)) {
            throw new NullPointerException("获取基础配置失败：paasId、paasToken、serverUrl。");
        }
        Signature sign = new Signature(paasId, paasToken);

        RestTemplate restTemplate = AppContextUtils.getBean(RestTemplate.class);
        boolean heanderIsNull = null == headerMap || headerMap.isEmpty() || headerMap.size() == 0;
        HttpHeaders headers = new HttpHeaders();
        if(!heanderIsNull && headerMap.containsKey(HttpHeaders.CONTENT_TYPE)) {
            String contentType = headerMap.get(HttpHeaders.CONTENT_TYPE);
            headers.setContentType(MediaType.parseMediaType(contentType));
            headers.remove(HttpHeaders.CONTENT_TYPE);
        } else {
            headers.setContentType(MediaType.APPLICATION_JSON);
        }
        if(!heanderIsNull && headerMap.containsKey(HttpHeaders.CACHE_CONTROL)) {
            headers.setCacheControl(headerMap.get(HttpHeaders.CACHE_CONTROL));
            headers.remove(HttpHeaders.CACHE_CONTROL);
        } else {
            headers.setCacheControl(CACHE_CONTROL);
        }
        if(!heanderIsNull) {
            headerMap.remove("x-tif-paasid");
            headerMap.remove("x-tif-timestamp");
            headerMap.remove("x-tif-signature");
            headerMap.remove("x-tif-nonce");
        }
        headers.add("x-tif-paasid", sign.getPaasId());
        headers.add("x-tif-timestamp", sign.getTimestamp());
        headers.add("x-tif-signature", sign.getSignature());
        headers.add("x-tif-nonce", sign.getNonce());
        if(!heanderIsNull && headerMap.size() > 0) {
            for(Map.Entry<String, String> kentry : headerMap.entrySet()) {
                if(StringTools.isNotBlank(kentry.getValue())) {
                    headers.add(kentry.getKey(), kentry.getValue());
                }
            }
        }
        if(headers.getContentType() == MediaType.APPLICATION_JSON) {
            MultiValueMap<String, Object> postParameters = new LinkedMultiValueMap<>();
            if(params != null) {
                Set<String> keySet = params.keySet();
                for (String key : keySet) {
                    postParameters.add(key, params.get(key));
                }
            }
            HttpEntity<MultiValueMap<String, Object>> request = new HttpEntity<MultiValueMap<String, Object>>(postParameters, headers);
            return restTemplate.exchange(serverUrl + apiUrl, HttpMethod.GET, request, classes);
        } else {
            String requestUrl = serverUrl + apiUrl;
            if(params != null && params.size() > 0) {
                String paramsstring = "?time=" + System.nanoTime();
                Set<String> keySet = params.keySet();
                for (String key : keySet) {
                    paramsstring = paramsstring.concat("&").concat(key).concat("=").concat(String.valueOf(params.get(key)));
                }
                requestUrl = requestUrl.concat(paramsstring);
            }
            HttpEntity<Resource> httpEntity = new HttpEntity<Resource>(headers);
            return restTemplate.exchange(requestUrl, HttpMethod.GET, httpEntity, classes);
        }
    }

    public static ResultData<String> downloadFileForDocExchange(String mediaId, String filePath, String pathPrefix, String attachmentTitle) throws Exception {
        String paasId = getPaasId(API_TYPE_DOC_EXCHANGE);
        String paasToken = getPaasToken(API_TYPE_DOC_EXCHANGE);
        String serverUrl = getServerUrl(API_TYPE_DOC_EXCHANGE);
        Signature sign = new Signature(paasId, paasToken);

        RestTemplate restTemplate = AppContextUtils.getBean(RestTemplate.class);
//		MultiValueMap<String, Object> postParameters = new LinkedMultiValueMap<>();
//		postParameters.add("media_id", mediaId);

        HttpHeaders headers = new HttpHeaders();
//		headers.setContentType(MediaType.APPLICATION_JSON);
//		headers.setCacheControl(CACHE_CONTROL);
        headers.add("x-tif-paasid", sign.getPaasId());
        headers.add("x-tif-timestamp", sign.getTimestamp());
        headers.add("x-tif-signature", sign.getSignature());
        headers.add("x-tif-nonce", sign.getNonce());



        String fileName = null;
        HttpEntity<Resource> httpEntity = new HttpEntity<Resource>(headers);
        String url = serverUrl + API_FILE_DOWNLOAD+"?media_id=" + mediaId;
        ResponseEntity<Resource> response = restTemplate.exchange(url, HttpMethod.GET, httpEntity, Resource.class);
        HttpHeaders responseHeaders = response.getHeaders();
        String contentDispositionString = "";
        List<String> contentDispositionList = responseHeaders.get("Content-Disposition");
        if(contentDispositionList != null) {
            for(String contentDisposition : contentDispositionList) {
                contentDispositionString = StringTools.append(contentDispositionString, contentDisposition,"；");
                if(StringUtils.containsIgnoreCase(contentDisposition, "filename")) {
                    fileName = contentDisposition.split("=")[1];
                    if(StringUtils.isNotBlank(fileName) && fileName.endsWith("\"")) {
                        fileName = fileName.substring(0, fileName.length() -1);
                    }
                }
            }
        }
        if(StringUtils.isBlank(fileName)) {
            ResultData<String> rd = ResultData.FAILURE("下载附件出错");
            logger.error(String.format("下载附件出错，获取不到文件名，url=%s, contentDispositionString = %s", url, contentDispositionString));
            return rd;
        }

        String docFileName = StringTools.generateUUID();
        String extensionFileName = FilenameUtils.getExtension(fileName);
        if(StringUtils.isBlank(extensionFileName)) {
            //文件名如果有问题，还是要下载下来
//            ResultData<String> rd = ResultData.FAILURE("下载附件出错");
            logger.error(String.format("下载附件出错，获取不到文件的扩展名，url=%s, contentDispositionString = %s, fileName = %s ", url, contentDispositionString, fileName));
            if(StringUtils.isNotBlank(attachmentTitle)) {
                extensionFileName = FilenameUtils.getExtension(attachmentTitle);
            }
//            return rd;
        }
        if(StringUtils.isNotBlank(extensionFileName)) {
            docFileName += "." + extensionFileName;
        }

        HttpStatus httpStatus = response.getStatusCode();
        int status = httpStatus.value();
        if(status != 200) {
            ResultData<String> rd = ResultData.FAILURE("下载附件出错");
            logger.error(String.format("下载附件出错，url=%s, httpStatus=%d", url, status));
            return rd;
        }
        Resource res = response.getBody();
        String path = null;
        if(res != null) {
            InputStream is = res.getInputStream();
            path = saveFile(is, filePath, pathPrefix, docFileName);
        } else {
            logger.error(String.format("没有文件，忽略，url=%s, httpStatus=%d， fileName=%s", url, status, fileName));
        }
        ResultData<String> rd = ResultData.SUCCESS();
        rd.setData(path);
        return rd;
    }

    public static JSONObject uploadFileForDocExchange(String filePath, String showFileName) throws Exception {
        String paasId = getPaasId(API_TYPE_DOC_EXCHANGE);
        String paasToken = getPaasToken(API_TYPE_DOC_EXCHANGE);
        String serverUrl = getServerUrl(API_TYPE_DOC_EXCHANGE);

        String originaFileName = showFileName;

        Signature sign = new Signature(paasId, paasToken);

        RestTemplate restTemplate = AppContextUtils.getBean(RestTemplate.class);

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
//		headers.setContentType(new MediaType("application" ,"octet-stream", Charset.forName("UTF-8")));  
        headers.setCacheControl(CACHE_CONTROL);
        headers.add("x-tif-paasid", sign.getPaasId());
        headers.add("x-tif-timestamp", sign.getTimestamp());
        headers.add("x-tif-signature", sign.getSignature());
        headers.add("x-tif-nonce", sign.getNonce());
//		logger.info(String.format("上传的文件名：%s", filePath));

        //处理不能上传的文件名
        showFileName = showFileName.replaceAll("\\r", " ");
        showFileName = showFileName.replaceAll("\\n", " ");
        String fileName = FilenameUtils.getBaseName(showFileName);
        fileName = fileName.replaceAll("\\.", "、");
        String extName = FilenameUtils.getExtension(showFileName);

        showFileName = fileName;
        if(StringUtils.isNotBlank(extName)) {
            showFileName += "." + extName;
        }

        CustomerFileSystemResource fileSystemResource = new CustomerFileSystemResource(filePath, showFileName);

        long fileSize = fileSystemResource.getFile().length();
//        logger.info(String.format("上传的文件大小：%d", fileSize));
        //上传文件不能超过40M
        if(fileSize > 1024*1024*40) {
            JSONObject rd = new JSONObject();
            rd.put("errcode", 909);
            rd.put("errmsg", "上传的文件不能超过40M");
            logger.error(String.format("[%s]上传的文件不能超过40M", originaFileName));
            return rd;

        }

        MultiValueMap<String, Object> form = new LinkedMultiValueMap<>();
        form.add("file", fileSystemResource);

        //用HttpEntity封装整个请求报文
        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<MultiValueMap<String, Object>>(form, headers);
        String url = serverUrl + API_FILE_UPLOAD;
//        System.out.println("url = " + url);
        JSONObject result = restTemplate.postForObject(serverUrl + API_FILE_UPLOAD, requestEntity, JSONObject.class);
//        logger.info(String.format("成功上传的结果：%s", result.toString()));
        if(RequestApiUtils.success(result)) {
//        	logger.info(String.format("成功上传的文件大小：%d", fileSize));
            result.put("file_size", fileSize);
        }
        return result;
    }

    private static String ERROR_CODE = "errcode";
    private static String ERROR_MSG = "errmsg";


    public static String getJosnStr(JSONObject json, String key) {
        if(json != null && json.containsKey(key)) {
            return json.getString(key);
        }

        return null;
    }
    public static Integer getJosnInt(JSONObject json, String key) {
        if(json != null && json.containsKey(key)) {
            return json.getInt(key);
        }

        return null;
    }

    public static JSONObject getJSONObject(JSONObject json, String key) {
        if(json != null && json.containsKey(key)) {
            return json.getJSONObject(key);
        }
        return null;
    }

    public static JSONArray getJSONArray(JSONObject json, String key) {
        if(json != null && json.containsKey(key)) {
            return json.getJSONArray(key);
        }
        return null;
    }


    /**
     * 判断api结果是否调用成功
     *
     * @param json
     * @return
     */
    public static boolean success(JSONObject json) {
        if (null != json && json.containsKey(ERROR_CODE)) {
            return json.getInt(ERROR_CODE) == 0;
        }
        return false;
    }

    /**
     * 获取错误信息
     *
     * @param json
     * @return
     */
    public static String getErrorMsg(JSONObject json) {
        if (json.containsKey(ERROR_MSG)) {
            return json.getString(ERROR_MSG);
        }
        return null;
    }

    public static int getErrorCode(JSONObject json) {
        if (json.containsKey(ERROR_CODE)) {
            return json.getInt(ERROR_CODE);
        }
        return 0;
    }

    private static String getServerUrl(String apiType) throws Exception {
        String key = apiType + "API_SERVER_URL";
        String serverUrl = getConfig(key);
        return serverUrl;
    }
    public static String getPaasId(String apiType) throws Exception {
        String key = apiType + "API_PAASID";
        String paasId = getConfig(key);
        return paasId;
    }
    public static String getPaasToken(String apiType) throws Exception {
        String key = apiType + "API_PAASTOKEN";
        String paasToken = getConfig(key);
        return paasToken;
    }

    private static String getConfig(String key) throws Exception {
        String value = SpringPropertyUtils.getPropertyValue(key);
        if (StringUtils.isBlank(value) ) {
            String msg = String.format("%s关键参数为空，请配置关键参数：%s", "广东政务网关平台", key);
            logger.error(msg);
            throw new Exception(msg);
        }
        return value;
    }

    //保存文件件到服务器中InputStream is
    private static String saveFile(InputStream is, String realPath, String pathPrefix, String fileName) {
        if (is == null) {
            return null;
        }
        if(realPath.endsWith("/")){
            realPath = realPath.substring(0, realPath.length()-1);
        }

        pathPrefix = StringUtils.defaultIfBlank(pathPrefix, "");

        String date = pathPrefix + "/" + new SimpleDateFormat("yyyyMM").format(Calendar.getInstance().getTime());
        String path = date + "/" + fileName;
        String filepath = realPath + path;
        File savefile = new File(filepath);
        if (!savefile.getParentFile().exists()) {
            savefile.getParentFile().mkdirs();
        }
//		FileUtil.writeBytes(data, savefile);
        FileUtil.writeFromStream(is, savefile);
        return path;
    }
}
